package booebill;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.*;

/**
 *
 * @author  lagaz
 */
public class TelaJogo extends javax.swing.JFrame implements Runnable
{
    //SOM
    private EfeitosSonoros Efeitos2 = new EfeitosSonoros();
    
    //PUBLIC PARA SE ACESSADA ATEH DA PQP
    public char cMatriz[][];//MATRIZAO  ADICIONAR!!!!!
    
    
    private static int iLargura = 800;
    private static int iAltura  = 600;
    
    private Thread tInicia;
    private boolean bJogando = false;
    private boolean bFim = false;
    //private boolean bMultiplayer = false;
    //private boolean bConectado = false;
    
    private Graphics gObjeto;
    private Image imgObjeto = null;
    
    private Image imgFundo = new ImageIcon(getClass().getResource("/fundo.png")).getImage();
    private int iLarguraFundo = imgFundo.getWidth(null);
    private int iAlturaFundo = imgFundo.getHeight(null);
    private int iFundoPosX=0;
    private int iFundoPosY=this.getContentPane().getFont().getSize()+3;
    
    private Bagulho bJogador;
    private Bagulho bHeroi[] = new Bagulho[10];
    private Tiro tTiro1 = null;
    private Tiro tTiro2 = null;
    private Tiro tTiro3 = null;
    private boolean bAtirando1 = false;
    private boolean bAtirando2 = false;
    private boolean bAtirando3 = false;
    
    private Image offScreen = null; // imagem auxiliar declarada na classe
    
    
    /*private String sIP;
     
    protected Socket SocketCliente = null;
    protected int iPorta = 1987;                      //apenas um valor default
    protected String sNomeDaMaquina = "127.0.0.1";    //apenas um valor default
    protected PrintWriter EnviaDados = null;
    protected BufferedReader brServer;
    protected DataOutputStream dtOut;*/
    
    /*
     * construtor do PanelTela
     * @param   iLargura    Largura da tela
     * @param   iAltura     Altura da tela
     */
    public TelaJogo(String sQual)
    {
        initComponents();
        setFocusable(true);
        requestFocus(); //agora recebe eventos de teclado.
        this.setSize(iLargura,iAltura);
        
        cMatriz=new char[iLargura+1][iAltura+1];               //MATRIZAO  ADICIONAR!!!!!
        
        //this.bMultiplayer = bMultiplayer;
        //this.sIP = sIP;
        
        bJogador = new Bagulho((iLargura-70),(iAltura/2),0,sQual);
        criaHerois();
        escutaTeclas();
        escutaTeclaTiro();
        
        ////////////////////////////adicionar////////////////////////////////////
        //Iniciando Matriz vazia
        for(int i=0 ; i<cMatriz.length ; i++)
        {
            for(int j=0 ; j<cMatriz[j].length ; j++)
            {
                cMatriz[i][j]='V';
            }
        }
        //COLOCANDO O BOO NA MATRIZ (OU O BILL)
        for(int i =0; i<64;i++)
        {
            {
                cMatriz[(bJogador.getX())][(bJogador.getY())+i]='B';
            }
        }
        for(int j=0; j<10; j++) //percorre entres os herois
        {
            for(int i =0; i<64;i++)
            {
                if((bHeroi[j].getX()>0) && (bHeroi[j].getY()>0)) //se heroi aparece na tela
                    cMatriz[(bHeroi[j].getX())][(bHeroi[j].getY())+i]='H';
            }
        }
        ////////////////////////////fim////////////////////////////////////////
        iniciaJogo();
        
    }
    
    /*
     * escutaTeclas        ouve as teclas
     */
    public void escutaTeclas()
    {
        addKeyListener( new KeyAdapter()
        {
            //ouve esc,q,ctrl+c
            public void keyPressed(KeyEvent e)
            {
                int iTecla = e.getKeyCode();
                if ((iTecla == KeyEvent.VK_ESCAPE) ||
                        (iTecla == KeyEvent.VK_Q) ||
                        ((iTecla == KeyEvent.VK_C) && e.isControlDown()))
                {
                    bJogando = false;
                }
                if((iTecla == KeyEvent.VK_UP) ||
                        (iTecla == KeyEvent.VK_W)  ||
                        (iTecla == KeyEvent.VK_8))
                {
                    //MOVENDO NA MATRIZ
                    if(bJogador.getY()>28) //GAMBIARRA!!
                    {
                        for(int i=0;i<10;i++)
                        {
                            //Abrindo espaco vago ao subir...
                            cMatriz[bJogador.getX()][bJogador.getY()+bJogador.getAltura()-i]='V';
                            //vendo limites
                            if(bJogador.getY()-10>=0)
                            {
                                if(cMatriz[bJogador.getX()][bJogador.getY()-i-1]=='V')
                                {
                                    cMatriz[bJogador.getX()][bJogador.getY()-i-1]='B';
                                }
                                else
                                {
                                    //ADICIONAR AQUI TALVEZ AS COMPARACOES COM OUTROS CARACTERES!!
                                    System.out.println("COLISAO DETECTADA!!! FAZER ALGUMA COISA!!");
                                }
                            }
                        }
                    }
                    ///////////////////
                    bJogador.moverY(-10,iAltura);
                }
                
                if((iTecla == KeyEvent.VK_DOWN) ||
                        (iTecla == KeyEvent.VK_S)  ||
                        (iTecla == KeyEvent.VK_2))
                {
                    
                    //MOVENDO NA MATRIZ
                    if(bJogador.getY()<528) //GAMBIARRA!!
                    {
                        for(int i=0;i<10;i++)
                        {
                            //Abrindo espaco vago ao subir...
                            cMatriz[bJogador.getX()][bJogador.getY()+i]='V';
                            //vendo limites
                            if(bJogador.getY()+10<800)
                            {
                                if(cMatriz[bJogador.getX()][bJogador.getY()+bJogador.getAltura()+i+1]=='V')
                                {
                                    cMatriz[bJogador.getX()][bJogador.getY()+bJogador.getAltura()+i+1]='B';
                                }
                                else
                                {
                                    //ADICIONAR AQUI TALVEZ AS COMPARACOES COM OUTROS CARACTERES!!
                                    System.out.println("COLISAO DETECTADA!!! FAZER ALGUMA COISA!!");
                                }
                            }
                        }
                    }
                    ///////////////////
                    bJogador.moverY(10,iAltura);
                }
            }
        });
    }
    
    
    /*
     * escutaTeclaTiro        ouve as teclas de tiro
     */
    public void escutaTeclaTiro()
    {
        addKeyListener( new KeyAdapter()
        {
            //ouve esc,q,ctrl+c
            public void keyPressed(KeyEvent e)
            {
                int iTecla = e.getKeyCode();
                if((iTecla == KeyEvent.VK_SPACE) ||
                        (iTecla == KeyEvent.VK_F))
                {
                    atira();
                }
            }
        });
    }
    
    /*
     * atira        verifica qual thread ja morreu para pode atirar (maximo de 3 tiros por vez)
     */
    public void atira()
    {
        if((tTiro1==null) || (!tTiro1.getTiro()))
        {
            //Colocando o tiro na matriz
            for(int i=0;i<6;i++)
            {
                cMatriz[bJogador.getX()-15][bJogador.getY()+32+i]='T';
            }
            //////////////////////////////
            tTiro1 = new Tiro(bJogador.getX()-15,bJogador.getY()+32,"/tiro-boo.png",10,iLargura,this);
            bAtirando1 = true;
        }
        else
        {
            if((tTiro2==null) || (!tTiro2.getTiro()))
            {
                
                //Colocando o tiro na matriz
                for(int i=0;i<6;i++)
                {
                    cMatriz[bJogador.getX()-15][bJogador.getY()+32+i]='T';
                }
                //////////////////////////////
                tTiro2 = new Tiro(bJogador.getX()-15,bJogador.getY()+32,"/tiro-boo.png",10,iLargura,this);
                bAtirando2 = true;
            }
            else
            {
                if((tTiro3==null) || (!tTiro3.getTiro()))
                {
                    
                    //Colocando o tiro na matriz
                    for(int i=0;i<6;i++)
                    {
                        cMatriz[bJogador.getX()-15][bJogador.getY()+32+i]='T';
                    }
                    //////////////////////////////
                    tTiro3 = new Tiro(bJogador.getX()-15,bJogador.getY()+32,"/tiro-boo.png",10,iLargura,this);
                    bAtirando3 = true;
                }
            }
        }
    }
    
    /*
     * addNotify        sobrepoe o metodo da classe JPanel que avisa que o componente tem um pai
     */
    public void addNotify()
    {
        super.addNotify();
        iniciaJogo();
    }
    
    /*
     * iniciaJogo       cria uma nova thread
     */
    public void iniciaJogo()
    {
        if(tInicia==null || !bJogando)
        {
            Efeitos2.SomMusica1();
            tInicia = new Thread(this);
            tInicia.start();
        }
    }
    
    /*
     * terminaJogo      encerra o jogo
     */
    public void terminaJogo()
    {
        //System.out.println("Partida terminada com "+bJogador.RetornaPontuacao());
        bJogando = false;
    }
    
    /*
     * criaHerois
     */
    public void criaHerois()
    {
        for(int i=0;i<10;i++)
        {
            System.out.println("Entrou no for. i="+i);
            int iAux=iAltura/2;
            do
            {
                iAux = (int)(Math.random()*(iAltura-63));
            } while((iAux<30) && (iAux>=(iAltura)));
            double dVelox=3;
            do
            {
                dVelox=Math.random()*3;
            } while((dVelox<2.5) && (dVelox>3.5));
            
            bHeroi[i] = new Bagulho((i*20-100),iAux,dVelox,"/mario.gif");
        }
    }
    
    
    
   /*
    * desenhaTela      desenha os elementos na tela
    */
    public Graphics desenhaTela(Graphics g)
    {
        /*                           FUNDO                              \*/
        if((iFundoPosX+iLarguraFundo*-1+1)<iLargura) //se o fundo de tela ainda esta na tela
        {
            //tudo que eh desenhado na tela
            g.drawImage(imgFundo, iFundoPosX+iLarguraFundo*-1+1, iFundoPosY, null);
            g.drawImage(imgFundo, iFundoPosX+iLarguraFundo*0, iFundoPosY, null);
            g.drawImage(imgFundo, iFundoPosX+iLarguraFundo*1-1, iFundoPosY, null);
            
            g.drawImage(bJogador.getImagem(), bJogador.getX(), bJogador.getY(), null);
            
            for(int i=0;i<10;i++)
            {
                if(bHeroi[i].getExiste())
                    g.drawImage(bHeroi[i].getImagem(), bHeroi[i].getX(), bHeroi[i].getY(), null);
            }
            
            if((bAtirando1) && (tTiro1!=null) && (tTiro1.getTiro()))
                g.drawImage(tTiro1.getImagem(),tTiro1.getX(),tTiro1.getY(),null);
            
            if((bAtirando2) && (tTiro2!=null) && (tTiro2.getTiro()))
                g.drawImage(tTiro2.getImagem(),tTiro2.getX(),tTiro2.getY(),null);
            
            if((bAtirando3) && (tTiro3!=null) && (tTiro3.getTiro()))
                g.drawImage(tTiro3.getImagem(),tTiro3.getX(),tTiro3.getY(),null);
            
        }
        else
        {
            g.drawImage(bJogador.getImagem(),bJogador.getX(),bJogador.getY(),null);
            g.drawString("Fim da fase!",370,300);
            bJogando=false;
            
            if(bJogador.getDescricao()=="boo")
            {
                //g.drawImage(imgFundoFimBoo,0,0,null);
            }
            else
            {
                //g.drawImage(imgFundoFimBill,0,0,null);
            }
        }
        return g;
    }
    /*
    public void conectar()
    {
        try
        {
            SocketCliente = new Socket(InetAddress.getByName(sNomeDaMaquina),iPorta);
            dtOut = new DataOutputStream(SocketCliente.getOutputStream());
            EnviaDados = new PrintWriter(SocketCliente.getOutputStream());
            brServer = new BufferedReader(new InputStreamReader(SocketCliente.getInputStream()));
            bConectado = true;
            System.out.println(" -> " + brServer.readLine());
     
        }
        catch(IOException e)
        {
            System.out.println(e);
        }
    }*/
    
    //MOVENDO TIRO PELA MATRIz
    /*
     * Classe para conseguir mover o tiro pela matriz de colisao
     * @param x localizacao X do tiro
     * @param y localizacao Y do tiro
     * @param x2 ponto para onde o tiro vai se mover
     * @return boolean retorna se ouve alguma colisao na substituicao
     */
    public boolean MoveTiro(int x, int y)//,int x2) //coloquei pra chamar o MoveTiro no run. acho q faz sentido
    {
        boolean retorno = false;
        char aux = ' ';
        if((x>=0))//&&(x2>=0))
        {
            aux=cMatriz[x][y];
            
            if(cMatriz[x][y]=='V')
            {
                cMatriz[x][y]='T';
            }
            else
            {
                System.out.println("TIRO COLIDINDO!!");
                retorno=true;
            }
        }
        return(retorno);
    }
    
    
    
    public void run()
    {
        //if((bMultiplayer) && (!bConectado))
        //     conectar();
        
        bJogando=true;
        while(bJogando)
        {
            
            //Informacoes de DEBUG
            System.out.println("Thread atual: "+Thread.currentThread());
            System.out.println("Thread Jogador: "+bJogador);
            System.out.println("Thread Tiro1: "+tTiro1);
            System.out.println("Thread Tiro2: "+tTiro2);
            System.out.println("Thread Tiro3: "+tTiro3);
            
            
            //PRECISO UMA MANEIRA DE PEGAR A POSICAO DO TIRO
            //Daniel: o tiro tem o getX e o getY
            
            //Se puder comentar como funciona o tiro, seria interessante....
            if((bAtirando1) && (!tTiro1.getTiro()))
                bAtirando1=false;
            
            if((bAtirando2) && (!tTiro2.getTiro()))
                bAtirando2=false;
            
            if((bAtirando3) && (!tTiro3.getTiro()))
                bAtirando3=false;
            
            if((tTiro1!=null) && (bAtirando1) && (tTiro1.getTiro()))
                MoveTiro(tTiro1.getX(), tTiro1.getY());
            if((tTiro2!=null) && (bAtirando2) && (tTiro2.getTiro()))
                MoveTiro(tTiro2.getX(), tTiro2.getY());
            if((tTiro3!=null) && (bAtirando3) && (tTiro3.getTiro()))
                MoveTiro(tTiro3.getX(), tTiro3.getY());
            
            // Se for tela cheia ou fixa, esse conteúdo pode ser colocado no disparador da Thread
            // Aumentando o desempenho do algoritmo.
            if ((offScreen==null)||(iLargura!=this.getWidth())||(iAltura!=this.getHeight()))
            {
                iLargura = this.getWidth();
                iAltura = this.getHeight();
                
                try
                {
                    Thread.sleep(50);
                }
                catch(Exception e)
                {
                }
                
                offScreen = this.createImage(this.getWidth(), this.getHeight());
            }
            ///////////////////////////////////////////////////////////////////////////////
            Graphics g = offScreen.getGraphics();
            paint(g);       //chama o paint que está vazio
            
            g = desenhaTela(g);
            
            g = this.getGraphics();
            g.drawImage(offScreen, 0, 0, this);
            
            /*                     Movendo o fundo                              \*/
            try
            {
                iFundoPosX++;
                Thread.sleep(100);
            }
            catch (InterruptedException e)
            {}
            /*                          -/-                              \*/
            
            for(int i=0;i<10;i++)
            {
                if(bHeroi[i]!=null) bHeroi[i].moverX();
            }
            
        }
        //Fim do bJogando
        try
        {
            Efeitos2.SomBill();
            Thread.sleep(500);
            this.setVisible(false);
            TelaEntrada tTela = new TelaEntrada();
            tTela.setVisible(true);
        }
        catch (InterruptedException e)
        {}
    }
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Código Gerado ">//GEN-BEGIN:initComponents
    private void initComponents()
    {

        getContentPane().setLayout(new javax.swing.BoxLayout(getContentPane(), javax.swing.BoxLayout.X_AXIS));

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        pack();
    }// </editor-fold>//GEN-END:initComponents
    
    // Declaração de variáveis - não modifique//GEN-BEGIN:variables
    // Fim da declaração de variáveis//GEN-END:variables
    
    
}
